# -*- coding: utf-8 -*-
"""
智能客服系统 - Flask应用
"""

import os
import sys
import json
from datetime import datetime
import numpy as np
import random
from flask import Flask, request, jsonify, session, send_from_directory

# 添加项目根目录到Python路径
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, project_root)

# 导入环境变量
from dotenv import load_dotenv
load_dotenv()

# 直接导入模块（因为backend目录已在Python路径中）
from llm_service import call_llm_api, simulate_llm_response

# 创建Flask应用实例
# 使用绝对路径配置静态文件目录
frontend_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'frontend')
app = Flask(__name__, static_folder=frontend_dir, static_url_path='/')
app.template_folder = frontend_dir

# 配置
app.config['JSON_AS_ASCII'] = False

# 会话管理配置
app.config['SESSION_PERMANENT'] = True
app.config['SESSION_TYPE'] = 'filesystem'

# 会话历史管理
conversation_histories = {}



# 导入知识服务模块
from knowledge_service import knowledge_service
import tempfile
from werkzeug.utils import secure_filename

# 配置上传文件夹
UPLOAD_FOLDER = os.path.join(tempfile.gettempdir(), 'rag_uploads')
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# 允许的文件扩展名
ALLOWED_EXTENSIONS = {'txt', 'md', 'json', 'csv'}

def allowed_file(filename):
    """
    检查文件扩展名是否允许
    """
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

# 添加示例知识库内容
try:
    knowledge_service.add_text("我们公司提供智能家居产品，包括智能灯光、智能插座、智能门锁等。", metadata={"source": "system", "type": "product_info"})
    knowledge_service.add_text("智能灯光功能：远程控制、定时开关、场景模式、语音控制、亮度调节。", metadata={"source": "system", "type": "product_info"})
    knowledge_service.add_text("售后政策：产品自购买之日起提供12个月保修期，支持7天无理由退换货。", metadata={"source": "system", "type": "service_info"})
    knowledge_service.add_text("购买流程：选择产品 - 加入购物车 - 填写订单信息 - 支付 - 等待收货。", metadata={"source": "system", "type": "service_info"})
    knowledge_service.add_text("设备重置方法：按住设备上的重置按钮5秒钟，直到指示灯闪烁。", metadata={"source": "system", "type": "product_info"})
except Exception as e:
    print(f"添加示例知识库内容时出错: {str(e)}")

# 知识库相关API端点
@app.route('/api/v2/knowledge/stats', methods=['GET'])
def get_knowledge_stats():
    """
    获取知识库统计信息
    """
    try:
        stats = knowledge_service.get_knowledge_stats()
        return jsonify(stats)
    except Exception as e:
        return jsonify({"success": False, "message": str(e)}), 500

@app.route('/api/v2/knowledge/add/text', methods=['POST'])
def add_text_to_knowledge():
    """
    添加文本到知识库
    """
    try:
        data = request.get_json()
        text = data.get('text', '')
        metadata = data.get('metadata', {})
        
        result = knowledge_service.add_text(text, metadata)
        if result['success']:
            return jsonify(result), 201
        else:
            return jsonify(result), 400
            
    except Exception as e:
        return jsonify({"success": False, "message": str(e)}), 500

@app.route('/api/v2/knowledge/upload', methods=['POST'])
def upload_document():
    """
    上传并添加单个文档到知识库
    """
    try:
        # 检查是否有文件部分
        if 'file' not in request.files:
            return jsonify({"success": False, "message": "没有文件部分"}), 400
            
        file = request.files['file']
        
        # 如果用户没有选择文件
        if file.filename == '':
            return jsonify({"success": False, "message": "未选择文件"}), 400
            
        # 检查文件类型
        if file and allowed_file(file.filename):
            # 保存文件到临时目录
            filename = secure_filename(file.filename)
            filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
            file.save(filepath)
            
            try:
                # 添加文档到知识库
                result = knowledge_service.add_document(filepath)
                if result['success']:
                    return jsonify(result), 201
                else:
                    return jsonify(result), 400
            finally:
                # 清理临时文件
                if os.path.exists(filepath):
                    os.remove(filepath)
        else:
            return jsonify({"success": False, "message": "不支持的文件类型"}), 400
            
    except Exception as e:
        return jsonify({"success": False, "message": str(e)}), 500

@app.route('/api/v2/knowledge/search', methods=['POST'])
def search_knowledge_v2():
    """
    在知识库中搜索相关文档
    """
    try:
        data = request.get_json()
        query = data.get('query', '')
        k = data.get('k', 5)
        filter = data.get('filter', None)
        
        result = knowledge_service.search_knowledge(query, k, filter)
        return jsonify(result)
        
    except Exception as e:
        return jsonify({"success": False, "message": str(e)}), 500

@app.route('/api/v2/knowledge/delete/<document_id>', methods=['DELETE'])
def delete_document_v2(document_id):
    """
    通过ID删除文档
    """
    try:
        result = knowledge_service.delete_document_by_id(document_id)
        if result['success']:
            return jsonify(result)
        else:
            return jsonify(result), 404
            
    except Exception as e:
        return jsonify({"success": False, "message": str(e)}), 500

@app.route('/api/v2/knowledge/delete/source', methods=['POST'])
def delete_documents_by_source():
    """
    删除来自特定源的所有文档
    """
    try:
        data = request.get_json()
        source_path = data.get('source_path', '')
        
        result = knowledge_service.delete_documents_by_source(source_path)
        return jsonify(result)
        
    except Exception as e:
        return jsonify({"success": False, "message": str(e)}), 500

@app.route('/api/v2/knowledge/clear', methods=['DELETE'])
def clear_knowledge():
    """
    清空知识库
    """
    try:
        # 为安全起见，要求确认
        data = request.get_json()
        confirm = data.get('confirm', False)
        
        if not confirm:
            return jsonify({"success": False, "message": "需要确认参数 confirm=true 才能清空知识库"}), 400
            
        result = knowledge_service.clear_knowledge_base()
        return jsonify(result)
        
    except Exception as e:
        return jsonify({"success": False, "message": str(e)}), 500

# 根路由，提供index.html
@app.route('/')
def index():
    """
    提供前端页面
    """
    return send_from_directory(app.static_folder, 'index.html')

# 系统提示词
SYSTEM_PROMPT = {
    'role': 'system',
    'content': '你是一个智能客服助手，需要友好、专业地回答用户的问题。请保持回答简洁明了，聚焦于用户的需求。'
}


@app.route('/api/chat', methods=['POST'])
def chat():
    """
    聊天API端点
    """
    try:
        # 获取请求数据
        data = request.get_json()
        user_message = data.get('message', '').strip()
        session_id = data.get('session_id', 'default')
        use_mock = data.get('use_mock', False)
        use_ollama = data.get('use_ollama', False)
        use_knowledge = data.get('use_knowledge', True)
        
        if not user_message:
            return jsonify({'error': '消息不能为空'}), 400
        
        # 初始化或获取会话历史
        if session_id not in conversation_histories:
            conversation_histories[session_id] = [SYSTEM_PROMPT]
        
        # 添加用户消息到历史记录
        conversation_histories[session_id].append({
            'role': 'user',
            'content': user_message
        })
        
        # 构建增强的提示词，包含知识库信息
        enhanced_conversation = conversation_histories[session_id].copy()
        knowledge_used = False
        
        if use_knowledge:
            try:
                # 使用ChromaDB知识库服务
                search_result = knowledge_service.search_knowledge(user_message, k=3)
                
                if search_result['success'] and search_result['results']:
                    knowledge_used = True
                    # 构建知识增强的用户消息
                    knowledge_text = " "
                    for result in search_result['results']:
                        if result['similarity_score'] > 50:  # 只使用相似度较高的文档
                            knowledge_text += result['content'] + " "
                    
                    # 替换最后一条用户消息，包含知识库信息
                    enhanced_conversation[-1]['content'] = f"用户问题: {user_message}\n相关知识: {knowledge_text}"
            except Exception as e:
                # 处理知识库搜索错误
                print(f"搜索知识库时出错: {str(e)}")
                knowledge_used = False
        
        # 获取LLM回复
        if use_mock:
            # 使用模拟回复（演示环境）
            llm_reply = simulate_llm_response(user_message, use_knowledge=use_knowledge)
        else:
            # 调用真实的LLM API
            llm_reply = call_llm_api(enhanced_conversation, use_ollama=use_ollama, use_knowledge=use_knowledge)
        
        # 添加AI回复到历史记录
        conversation_histories[session_id].append({
            'role': 'assistant',
            'content': llm_reply
        })
        
        # 限制历史记录长度，防止内存占用过大
        if len(conversation_histories[session_id]) > 20:
            # 保留系统提示词，移除最旧的对话
            conversation_histories[session_id] = [SYSTEM_PROMPT] + conversation_histories[session_id][-18:]
        
        # 返回响应
        return jsonify({
            'reply': llm_reply,
            'knowledge_used': knowledge_used
        })
    
    except Exception as e:
        print(f"处理聊天请求异常: {str(e)}")
        return jsonify({
            'error': str(e),
            'knowledge_used': False
        }), 500


@app.route('/api/reset', methods=['POST'])
def reset():
    """
    重置会话历史
    """
    try:
        data = request.get_json()
        session_id = data.get('session_id', 'default')
        
        if session_id in conversation_histories:
            del conversation_histories[session_id]
        
        return jsonify({'status': 'success'})
    except Exception as e:
        return jsonify({'error': str(e)}), 500


@app.errorhandler(404)
def not_found(error):
    """
    处理404错误，返回前端页面
    """
    return send_from_directory(app.static_folder, 'index.html')


def main():
    """
    主函数入口
    """
    port = int(os.getenv('PORT', 8000))
    host = os.getenv('HOST', '0.0.0.0')
    debug = os.getenv('DEBUG', 'True').lower() == 'true'
    
    print(f"服务器启动在 http://{host}:{port}")
    print(f"DEBUG模式: {debug}")
    
    app.run(host=host, port=port, debug=debug)


if __name__ == '__main__':
    main()